package com.woniuxy.qiantai.controller;


import com.google.code.kaptcha.Producer;
import com.woniuxy.qiantai.entity.User;
import com.woniuxy.qiantai.service.UserService;
import com.woniuxy.qiantai.utils.CookieUtils;
import com.woniuxy.qiantai.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author woniumrwang
 * @since 2023-01-08 07:35:18
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    Producer producer;
    @Autowired
    UserService userService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    JavaMailSender javaMailSender;

    @RequestMapping("getKaptchaImage")
    public void getKaptchaImage(HttpServletResponse response, HttpSession httpSession) throws IOException {
        //生成验证码
        String code = producer.createText();
        code = "0000";
        httpSession.setAttribute("kaptchaCode", code);
        BufferedImage image = producer.createImage(code);
        response.setContentType("image/png");
        ImageIO.write(image, "png", response.getOutputStream());
    }

    @PostMapping("login")
    public String login(String username, String password, String code, HttpSession session, Model model, HttpServletResponse response) {
        System.out.println(username);
        System.out.println(password);
        System.out.println(code);
        //校验验证码
        String kapcheCode = (String) session.getAttribute("kaptchaCode");
        if (StringUtils.isEmpty(code) || !code.equals(kapcheCode)) {
            model.addAttribute("errorInfo", "验证码错误");
            return "login";
        }
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            model.addAttribute("errorInfo", "用户名或密码不能为空");
            return "login";
        }
        User userByAccount = userService.getUserByAccount(username);
        if (Objects.isNull(userByAccount) || !userByAccount.getPassword().equals(password)) {
            model.addAttribute("errorInfo", "用户名或者密码错误");
            return "login";
        }
        //登录成功
        //session.setAttribute("currentAccount", userByAccount.getAccount());
        //使用jwt和Cookie 存储用户账号
        String token = JwtUtils.createToken(userByAccount.getAccount(), 15);
        CookieUtils.setUserToken2Cookie(response, token);
        //在Redis里也保存一份信心，有效期设置30分钟
        stringRedisTemplate.opsForValue().set(token, userByAccount.getAccount(), 30, TimeUnit.MINUTES);
        //重定向
        return "redirect:/";
    }

    @RequestMapping("currentAccount")
    @ResponseBody
    public String currentAccount(HttpSession session, HttpServletRequest request) {
        //从sess中获取账号
        String account = "";
        //String currentAccount = (String) session.getAttribute("currentAccount");
        //从cookie中读取token 然后通过jwt解析token得到currentAccount
        String userToken2Cookie = CookieUtils.getUserToken2Cookie(request);
        String currentAccount = JwtUtils.getAccountWithoutException(userToken2Cookie);
        System.out.println("currentAccount" + currentAccount);
        account = StringUtils.isEmpty(currentAccount) ? account : currentAccount;
        return account;
    }

    @RequestMapping("loginout")
    public String loginout(HttpSession session, HttpServletResponse response, HttpServletRequest request) {
        //移除session中的账号信息
        //session.removeAttribute("currentAccount");
        //删除保存了token数据的cookie
        CookieUtils.deleteUserTokenFromCookie(response);
        //删除Redis中的信息
        String userToken2Cookie = CookieUtils.getUserToken2Cookie(request);
        if (!StringUtils.isEmpty(userToken2Cookie)) {
            stringRedisTemplate.delete(userToken2Cookie);
        }
        return "redirect:/";
    }

    @RequestMapping("redirectLoginHtml")
    public String redirectLoginHtml() {
        //重定向到登录页面
        return "redirect:/login.html";
    }

    @RequestMapping("getEmailCode")
    @ResponseBody
    public String getEmailCode(String emailAddress) {
        //正则表达式校验邮箱
        String regex = "^(.+)@(.+)$";
        Pattern pattern = Pattern.compile(regex);
        boolean isOk = pattern.matcher(emailAddress).matches();
        if (!isOk) {
            return "请输入正确的邮箱";
        }
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom("1129740260@qq.com");
        simpleMailMessage.setTo(emailAddress);
        simpleMailMessage.setSubject("验证码");
        String code = producer.createText();
        simpleMailMessage.setText("您的验证码为：" + code);
        javaMailSender.send(simpleMailMessage);
        //将验证码存入Redis中
        stringRedisTemplate.opsForValue().set(emailAddress, code, 5, TimeUnit.MINUTES);
        return "ok";
    }

    @RequestMapping("reg")
    public String reg(String username, String password, String repass, String email, String emailCode, Model model) {
        //校验邮箱验证码
        String redisEmailCode = stringRedisTemplate.opsForValue().get(email);
        System.out.println("emailCode:"+emailCode);
        System.out.println("redisEmailCode:"+redisEmailCode);
        if (StringUtils.isEmpty(redisEmailCode) || !Objects.equals(emailCode, redisEmailCode)) {
            //如果根据注册邮箱在Redis中取到的验证码为null 或者Redis中的验证码和页面提交的不相同
            model.addAttribute("errorInfo", "验证码错误");
            return  "register";
        }
        //增加同步锁
        //校验用户名唯一
        synchronized (username.intern()){
        if (Objects.nonNull(userService.getUserByAccount(username)) || StringUtils.isEmpty(username)) {
            model.addAttribute("errorInfo", "用户名被占用，请重新选输入");
            return  "register";
        }
        //校验邮箱唯一
        if (StringUtils.isEmpty(email) || Objects.nonNull(userService.getUserByEmail(email))) {
            model.addAttribute("errorInfo", "邮箱被注册，请重新选输入");
            return  "register";
        }
        if (StringUtils.isEmpty(repass) || !Objects.equals(repass, password)) {
            model.addAttribute("errorInfo", "前后密码不一致，请重新选输入");
            return  "register";
        }
        userService.reg(username,password,email);
        }
        return "login";
    }
}

